﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace System.IO
{
	public static class _StreamReaderExtensions
	{
		static readonly FieldInfo _fiCharBuffer = typeof(StreamReader).GetField("charBuffer", BindingFlags.Instance | BindingFlags.NonPublic),
			_fiCharLen = typeof(StreamReader).GetField("charLen", BindingFlags.Instance | BindingFlags.NonPublic),
			_fiCharPos = typeof(StreamReader).GetField("charPos", BindingFlags.Instance | BindingFlags.NonPublic);

		public static void UnBufferData(this StreamReader rThis)
		{
			if (!rThis.BaseStream.CanSeek)
				throw new InvalidOperationException("Can not perform 'unbuffering' because the underlying Stream can't Seek.");

			int charLen = (int)_fiCharLen.GetValue(rThis),
				charPos = (int)_fiCharPos.GetValue(rThis);

			rThis.BaseStream.Seek(charPos - charLen, SeekOrigin.Current);
			rThis.DiscardBufferedData();			
		}
		public static byte[] GetBufferedData(this StreamReader rThis)
		{
			char[] charBuffer = (char[])_fiCharBuffer.GetValue(rThis);
			int charLen = (int)_fiCharLen.GetValue(rThis),
				charPos = (int)_fiCharPos.GetValue(rThis);

			char[] remaining = new char[charLen - charPos];
			Array.Copy(charBuffer, charPos, remaining, 0, charLen - charPos);
			return rThis.CurrentEncoding.GetBytes(remaining);
		}
	}
}
